home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 19 / madtrb14.zip / IO.INC < prev    next >
Text File  |  1985-10-05  |  19KB  |  744 lines

  1. var
  2.   cancelled : boolean;
  3.   inbuffer  : line;
  4.  
  5. function charin(withecho: boolean):char; forward;
  6.  
  7. procedure sendout(ch: char);
  8.  
  9. {Character output - bypasses word-wrap; also performs
  10.  "pause" and "abort" input character checks.}
  11.  
  12.   var temp: char;
  13.       tctl: boolean;
  14.  
  15.   begin
  16.     if not cancelled then begin
  17.       if inready then begin
  18.         temp := charin(noecho);
  19.         if (temp = pause) or (upcase(temp) = 'S') then begin
  20.           tctl := controls;
  21.           controls := true;
  22.           temp := charin(noecho);
  23.           controls := tctl;
  24.         end;
  25.         if (temp = abort) or (upcase(temp) = 'C') then cancelled := true;
  26.       end;
  27.       xmitchar(ch);
  28.       write(ch);
  29.       if printon then write(lst, ch);
  30.       if (ch = cr) and (lf = null) then writeln;
  31.     end;
  32.   end;
  33.  
  34. procedure flushbuff;
  35.  
  36.   var
  37.     outpointer: byte;
  38.  
  39.   begin
  40.     if length(buffer) > lastspace then
  41.       for outpointer := lastspace + 1 to length(buffer) do
  42.         sendout(buffer[outpointer]);
  43.     lastspace := length(buffer);
  44.   end;
  45.  
  46. procedure resetbuff;
  47.  
  48.   begin
  49.     bufpointer := 0;
  50.     lastspace := 0;
  51.     charcount := 0;
  52.     buffer := '';
  53.   end;
  54.  
  55. procedure charout(ch:char);
  56.  
  57. {Character output using word-wrap}
  58.  
  59.   var
  60.     buffull   : boolean;
  61.     temp      : long;
  62.  
  63.   begin
  64.     if caps then ch := upcase(ch);
  65.     if not (ch in [null..#31]) then charcount := succ(charcount);
  66.     if (ch = bs) and (charcount > 0) then charcount := charcount - 1;
  67.     buffer := buffer + ch;
  68.     bufpointer := length(buffer);
  69.     buffull := (charcount + 2 > width);
  70.     if buffull then begin
  71.       if (lastspace > 0)
  72.         then begin
  73.           buffer := copy(buffer, lastspace + 1, bufpointer - lastspace);
  74.           charcount := length(buffer);
  75.           lastspace := 0;
  76.           end {then}
  77.         else begin
  78.           flushbuff;
  79.           resetbuff;
  80.         end; {else}
  81.       sendout(cr);
  82.       sendout(lf);
  83.     end; {if}
  84.     if ch in [null..space] then flushbuff;
  85.     if (ch=cr) then resetbuff;
  86.   end;
  87.  
  88. procedure stringout(message:line);
  89.  
  90.   var
  91.     charpos: integer;
  92.  
  93.   begin
  94.     for charpos := 1 to length(message) do charout(message[charpos]);
  95.   end;
  96.  
  97. procedure lineout; (* "forward" declared in MACHDEP *)
  98.  
  99.   begin
  100.     stringout(message);
  101.     charout(cr);
  102.     charout(lf);
  103.   end;
  104.  
  105. function timedin: boolean;
  106.  
  107. {returns false if no character received in within
  108.  one second: used for XMODEM and input timeout.}
  109.  
  110.   var times: integer;
  111.  
  112.   begin
  113.     times := 0;
  114.     while (times < 500) and not inready do begin
  115.       times := times + 1;
  116.       delay(2);
  117.     end;
  118.     timedin := inready and cts;
  119.   end;
  120.  
  121. function charin;
  122.  
  123.   var
  124.     ch: char;
  125.     countime: integer;
  126.  
  127.   begin
  128.     ch := null;
  129.     countime := 0;
  130.     repeat
  131.       if timedin then ch := recvchar else countime := countime + 1;
  132.       if keypressed then read(kbd, ch);
  133.       if countime > 300 then hangup;
  134.       if not cts then ch := cr;
  135.       if (ch <> bs) and not controls then ch := chr(ord(ch) and 127);
  136.     until (ch in [abort, pause, bs, tab, cr, space..#127])
  137.       or (controls and (ch <> null));
  138.     if (ch = #127) and not controls then ch := bs;
  139.     if ch = #$8D then ch := cr;
  140.     if withecho then begin
  141.       sendout(ch);
  142.       if ch = bs then begin sendout(' '); sendout(bs); end;
  143.     end;
  144.     charin := ch;
  145.   end;
  146.  
  147.  
  148. (* procedure flush;
  149.  
  150.   var
  151.     junk: char;
  152.  
  153.   begin
  154.     while inready do junk := charin(noecho);
  155.     clearstatus;
  156.   end;
  157.              duplicated procedure. so it is deleted !   *)
  158.  
  159.  
  160. function inputstring(withecho: boolean): line;
  161.  
  162.   var
  163.     temp:    line;
  164.     ch:      char;
  165.  
  166.   begin
  167.     temp := '';
  168.     flush;
  169.     repeat
  170.       ch := charin(noecho);
  171.       if (ch = bs) then begin
  172.         if length(temp) > 0 then begin
  173.           temp := copy(temp, 1, length(temp) - 1);
  174.           if withecho then begin
  175.             sendout(bs);
  176.             sendout(space);
  177.             sendout(bs);
  178.           end;
  179.         end;
  180.       end
  181.       else begin
  182.         if (ch <> cr) and (length(temp) < 80)
  183.         and ((ch in [tab, space..#126]) or controls) then begin
  184.           if ch = tab then repeat
  185.             temp := temp + space;
  186.             if withecho then sendout(space);
  187.           until (length(temp) mod 8) = 0
  188.           else begin
  189.             temp := temp + ch;
  190.             if withecho then sendout(ch);
  191.           end; {else}
  192.         end
  193.         else if (ch <> cr) then sendout(bell);
  194.       end;
  195.     until (ch = cr);
  196.     charout(cr); charout(lf);
  197.     inputstring := temp;
  198.   end;
  199.  
  200. function getinput(prompt:line; maxlength:integer; withecho:boolean):line;
  201.  
  202.   var posn: integer;
  203.       temp: char;
  204.  
  205.   begin
  206.     if cancelled then begin
  207.       cancelled := false;
  208.       lineout(space);
  209.     end;
  210.     if inbuffer = '' then begin
  211.       repeat
  212.         cancelled := false;
  213.         stringout(prompt);
  214.         if bl = bell then stringout(bl);
  215.       until cancelled = false;
  216.       inbuffer := inputstring(withecho);
  217.     end;
  218.     if maxlength = 1 then begin
  219.       if inbuffer = '' then temp := cr else begin
  220.         temp := inbuffer[1];
  221.         inbuffer := copy(inbuffer, 2, length(inbuffer)-1);
  222.         if (length(inbuffer) > 1) and (inbuffer[1] = ';')
  223.           then inbuffer := copy(inbuffer, 2, length(inbuffer)-1);
  224.       end; {else}
  225.       getinput := temp;
  226.     end
  227.     else begin
  228.       posn := pos(';', inbuffer);
  229.       if posn = 0 then posn := length(inbuffer) + 1;
  230.       if posn > maxlength then begin
  231.         posn := maxlength + 1;
  232.         inbuffer := copy(inbuffer, 1, maxlength);
  233.       end;
  234.       getinput := copy(inbuffer, 1, posn - 1);
  235.       if posn >= length(inbuffer)
  236.         then inbuffer := ''
  237.         else inbuffer := copy(inbuffer, posn + 1, length(inbuffer) - posn);
  238.     end;
  239.   end;
  240.  
  241. function allcaps(letters: person): person;
  242.  
  243.   var
  244.     loop: byte;
  245.     temp: person;
  246.  
  247.   begin
  248.     temp := '';
  249.     for loop := 1 to length(letters) do
  250.       temp := temp + upcase(letters[loop]);
  251.     allcaps := temp;
  252.   end;
  253.  
  254. procedure awaitcall;
  255.  
  256.   var
  257.     junk: char;
  258.  
  259.   begin
  260.     setbaud(fast);
  261.     writeln(cr + lf + 'Waiting for call...');
  262.     flush;
  263.     repeat
  264.       if keypressed then begin
  265.         read(kbd, junk);
  266.         local := junk = esc;
  267.         if local then setlocal else exitchar := junk;
  268.       end;
  269.     until cts or (exitchar = abort);
  270.     clrscr;
  271.     if exitchar <> abort then begin
  272.       if local then writeln('Local control.') else writeln('On line...');
  273.       delay(400);
  274.       flush;
  275.       junk := charin(noecho);
  276.       if badframe or (junk <> cr) then setbaud(slow);
  277.     end;
  278.   end;
  279.  
  280. procedure clearsc;
  281.  
  282.   begin
  283.     stringout(cs);
  284.     delay(500);   {allows time for slow terminal screen clears}
  285.   end;
  286.  
  287. function getcap(prompt: line): char;
  288.  
  289.   begin
  290.     getcap := upcase(getinput(prompt, 1, echo));
  291.   end;
  292.  
  293. function getint(nmax, star: integer; prompt: line): integer;
  294.  
  295.   var temp, test: integer;
  296.       outstr, userin: name;
  297.  
  298.   begin
  299.     str(nmax:4, outstr);
  300.     repeat
  301.       temp := 0;
  302.       userin := getinput(prompt, 4, echo);
  303.       val(userin, temp, test);
  304.       if (temp > nmax) then lineout('Number too large: ' + outstr + ' maximum.');
  305.     until ((test = 0) and (temp >= 0) and (temp <= nmax))
  306.      or (userin = '*') or (userin = '') or (userin = '?') or not cts;
  307.      if userin = '?' then getint := -1
  308.       else if userin = '*' then getint := star
  309.        else if test = 0 then getint := temp
  310.         else getint := 0;
  311.   end;
  312.  
  313. {Real-time clock support starts here...
  314.  these routines must remain, even if there's
  315.  no clock! To kill clock support, simply set
  316.  "clockin" in BBS.PAS to false.}
  317.  
  318. type monthname = string[3];
  319.      monames  = array[1..12] of monthname;
  320.  
  321. const months: monames = ('Jan','Feb','Mar','Apr','May','Jun',
  322.                          'Jul','Aug','Sep','Oct','Nov','Dec');
  323.  
  324. function time(month, date, hour, min, sec: byte): name;
  325.  
  326. {Returns 14-character string containing time and date}
  327.  
  328.   var
  329.     temps,
  330.     tempm,
  331.     tempd,
  332.     temph: string[2];
  333.  
  334.   begin
  335.     if clockin then begin
  336.       str(sec:2,temps);
  337.       str(min:2,tempm);
  338.       str(hour:2,temph);
  339.       str(date:2,tempd);
  340.       if sec < 10 then temps := '0' + temps[2];
  341.       if min < 10 then tempm := '0' + tempm[2];
  342.       if date < 10 then tempd := '0' + tempd[2];
  343.       time := temph + ':' + tempm + ':' + temps + ' ' + months[month] + tempd;
  344.     end
  345.     else time := '';
  346.   end;
  347.  
  348. procedure showtime;
  349.  
  350.   var
  351.     message: name;
  352.  
  353.   begin
  354.     if clockin then begin
  355.       clock(month, date, hour, min, sec);
  356.       message := time(month, date, hour, min, sec);
  357.       lineout('Time is: ' + message);
  358.     end;
  359.   end;
  360.  
  361. procedure calcconnect(var usehour, usemin, usesec: integer);
  362.  
  363.   begin
  364.     clock(month, date, hour, min, sec);
  365.     usemin := 0;
  366.     usehour := 0;
  367.     usesec := sec - onsec;
  368.     if usesec < 0 then begin
  369.       usesec := usesec + 60;
  370.       usemin := -1;
  371.     end;
  372.     usemin := min - onmin + usemin;
  373.     if usemin < 0 then begin
  374.       usemin := usemin + 60;
  375.       usehour := -1;
  376.     end;
  377.     usehour := hour - onhour + usehour;
  378.     if usehour < 0 then usehour := usehour + 24;
  379.   end;
  380.  
  381. procedure connecttime;
  382.  
  383.   var
  384.     message: name;
  385.  
  386.   begin
  387.     if clockin then begin
  388.       calcconnect(usehour, usemin, usesec);
  389.       message := copy(time(1, 1, usehour, usemin, usesec), 1, 8);
  390.       lineout('Connect time: ' + message);
  391.     end;
  392.   end;
  393.  
  394. procedure searchlib(infile: name; var result, libsects: integer);
  395.  
  396. {Library-file support adapted from DELIB.PAS
  397.  by Bela Lubkin of Borland International.}
  398.  
  399.   var
  400.     temp: name;
  401.     dirlength, offset, firstsec, loop, chrpos: integer;
  402.  
  403.   begin
  404.     firstsec := 0; libsects := 0;
  405.     blockread(libfile, libbuff, 1);
  406.     if libbuff[0] <> 0 then result := 1;
  407.     loop := 1;
  408.     while (result = 0) and (loop <= 11) do begin
  409.       if libbuff[loop] <> 32 then result := 1;
  410.       loop := loop + 1;
  411.     end;
  412.     result := result + libbuff[12] + libbuff[13];
  413.     if result = 0 then begin
  414.       dirlength := libbuff[14] + 256*libbuff[15];
  415.       if dirlength = 0 then result := 1;
  416.     end;
  417.     if result = 0 then begin
  418.       loop := 0;
  419.       while (loop < 4*dirlength-1) and (result = 0) and (firstsec = 0) do begin
  420.         loop := loop + 1;
  421.         offset := 32*(loop mod 4);
  422.         if offset = 0 then blockread(libfile, libbuff, 1);
  423.         if libbuff[offset] <> 0 then result := 1
  424.         else begin
  425.           temp := '';
  426.           for chrpos := 1 to 8 do
  427.             if libbuff[offset + chrpos] <> 32 then
  428.               temp := temp + chr(libbuff[offset + chrpos]);
  429.           if libbuff[offset + 9] <> 32 then begin
  430.             temp := temp + '.';
  431.             for chrpos := 9 to 11 do
  432.               if libbuff[offset + chrpos] <> 32 then
  433.                 temp := temp + chr(libbuff[offset + chrpos]);
  434.           end;
  435.           if cts and (infile = 'DIR') then lineout(temp);
  436.           if infile = temp then begin
  437.             firstsec := libbuff[offset+12] + 256*libbuff[offset+13];
  438.             libsects := libbuff[offset+14] + 256*libbuff[offset+15];
  439.             seek(libfile, firstsec);
  440.           end;
  441.         end;
  442.       end;
  443.       if infile = 'DIR' then result := 0;
  444.     end;
  445.   end;
  446.  
  447. procedure libassign(filename: longname; var result: integer);
  448.  
  449.   var
  450.     infile: name;
  451.     slash: integer;
  452.     library: boolean;
  453.  
  454.   begin
  455.     result := 0;
  456.     slash := pos('/', filename);
  457.     library := (slash > 0);
  458.     if library then begin
  459.       infile := copy(filename, slash + 1, length(filename) - slash);
  460.       filename := copy(filename, 1, slash - 1);
  461.       if pos('.', filename) = 0 then filename := filename + '.LBR';
  462.     end;
  463.     assign(libfile, filename);
  464.     {$I-} reset(libfile) {$I+};
  465.     result := IOresult;
  466.     if result = 0 then
  467.       if library then searchlib(infile, result, libsects)
  468.       else libsects := filesize(libfile);
  469.     libeof := (libsects = 0);
  470.   end;
  471.  
  472. procedure libblockread(var fileblock: filbuffer);
  473.  
  474.   begin
  475.     if libsects > 0 then blockread(libfile, fileblock, 1);
  476.     libsects := libsects - 1;
  477.     if libsects = 0 then libeof := true;
  478.   end;
  479.  
  480. procedure typefile(fname: longname; nowrap: boolean);
  481.  
  482. {Inline unsqueezer adapted from USQ.PAS V1.3, which
  483.  was written by Scott Loftesness, adapted for Turbo
  484.  Pascal by Steve Freeman and made compatible with
  485.  Non-Turbo Pascal squeezers by myself.- BM}
  486.  
  487.   const
  488.     recognize  = $FF76;
  489.     numvals    = 257;      { max tree size + 1 }
  490.     speof      = 256;      { special end of file marker }
  491.     dle: char  = #$90;
  492.  
  493.   type
  494.     tree       = array [0..255,0..1] of integer;
  495.  
  496.   var
  497.     in_ptr, result: integer;
  498.     in_buff: filbuffer;
  499.     dnode: tree;
  500.     inchar, curin, filecksum, bpos, i, repct, numnodes: integer;
  501.     c, lastchar: char;
  502.     origfile: name;
  503.     squeezed, eofin: boolean;
  504.  
  505.   function getc: integer;
  506.  
  507.     begin
  508.       in_ptr := in_ptr + 1;
  509.       if in_ptr > 127 then begin
  510.         if libeof then eofin := true
  511.         else begin
  512.           libblockread(in_buff);
  513.           in_ptr := 0;
  514.         end;
  515.       end;
  516.       if eofin then getc := 26 else getc := in_buff[in_ptr];
  517.     end;
  518.  
  519.   function getw: integer;
  520.  
  521.     var in1,in2: integer;
  522.  
  523.     begin
  524.       in1 := getc; in2 := getc;
  525.       getw := in1 + in2 shl 8;
  526.     end;
  527.  
  528.   procedure initialize;
  529.  
  530.     var str: string[14];
  531.  
  532.     begin
  533.       in_ptr := 127; squeezed := true;
  534.       repct:=0;   bpos:=99;   origfile:='';   eofin:=false;
  535.       i := getw;
  536.       if (recognize <> i) then begin
  537.         squeezed := false;
  538.         in_ptr := -1;
  539.       end
  540.       else begin
  541.         filecksum := getw;     { get checksum from chars 2 - 3 of file }
  542.         repeat    { build original file name }
  543.           inchar:=getc;
  544.           if inchar <> 0
  545.             then origfile := origfile + chr(inchar);
  546.         until inchar = 0;
  547.         lineout('Original file: ' + origfile);
  548.         numnodes:=ord(getw); { get the number of nodes in this files tree }
  549.         if (numnodes<0) or (numnodes>=numvals) then begin
  550.           squeezed := false;
  551.           in_ptr := -1;
  552.         end;
  553.       end;
  554.       if squeezed then begin
  555.         dnode[0,0]:= -(speof+1);
  556.         dnode[0,1]:= -(speof+1);
  557.         numnodes:=numnodes-1;
  558.         for i:=0 to numnodes do begin
  559.           dnode[i,0]:=getw;
  560.           dnode[i,1]:=getw;
  561.         end;
  562.       end;
  563.     end;
  564.  
  565.   function getuhuff: char;
  566.  
  567.     var i: integer;
  568.  
  569.     begin
  570.       i:=0;
  571.       repeat
  572.         bpos:=bpos+1;
  573.         if bpos>7 then begin
  574.           curin := getc;
  575.           bpos:=0;
  576.         end
  577.         else curin := curin shr 1;
  578.         i := ord(dnode[i,ord(curin and $0001)]);
  579.       until (i<0);
  580.       i := -(i+1);
  581.       if i=speof then begin
  582.         eofin:=true;
  583.         getuhuff:=chr(26);
  584.       end
  585.       else getuhuff:=chr(i);
  586.     end;
  587.  
  588.   function getcr: char;
  589.  
  590.     var c: char;
  591.  
  592.     begin
  593.       if squeezed then begin
  594.         if (repct>0) then begin
  595.           repct:=repct-1;
  596.           getcr:=lastchar;
  597.         end
  598.         else begin
  599.           c:=getuhuff;
  600.           if c<>dle then begin
  601.             getcr:=c;
  602.             lastchar:=c;
  603.           end
  604.           else begin
  605.             repct:=ord(getuhuff);
  606.             if repct=0 then getcr:=dle
  607.             else begin
  608.               repct:=repct-2;
  609.               getcr:=lastchar;
  610.             end;
  611.           end;
  612.         end;
  613.       end
  614.       else getcr := chr(getc);
  615.     end; {getcr}
  616.  
  617.   begin
  618.     libassign(fname, result);
  619.     if result <> 0 then lineout('Can''t find ' + fname + '!')
  620.     else begin
  621.       initialize;
  622.       while cts and not(cancelled or eofin) do begin
  623.         c:=getcr;
  624.         if c = #26 then eofin := true else begin
  625.           if nowrap then begin
  626.             if c <> #$8D then begin { <-- Allows no-wrap using WordStar files}
  627.               c := chr(ord(c) and 127);
  628.               if (c <> lnfd) then charout(c);
  629.               if c = cr then charout(lf);
  630.             end;
  631.           end else sendout(c);
  632.         end;
  633.       end;
  634.       close(libfile);
  635.     end;
  636.     unload;
  637.   end;
  638.  
  639. procedure outfile(fname: longname);
  640.  
  641.   begin
  642.     typefile(fname, true);
  643.   end;
  644.  
  645. function findid(caller: person): integer;
  646.  
  647.   var
  648.     usernum: integer;
  649.     index: integer;
  650.  
  651.   begin
  652.     usernum := 0;
  653.     index := 0;
  654.     lineout('Searching userlist...');
  655.     {$I-} reset(idfile) {$I+};
  656.     if IOresult <> 0 then rewrite(idfile);
  657.     while (usernum = 0) and not eof(idfile) do begin
  658.       index := index + 1;
  659.       read(idfile, idrec);
  660.       if idrec.user = caller then usernum := index;
  661.     end;
  662.     findid := usernum;
  663.   end;
  664.  
  665. procedure getcomments(maxline: integer);
  666.  
  667.   var
  668.     comfile: file of line;
  669.     linenum: integer;
  670.     head, temp: line;
  671.  
  672.   begin
  673.     str(maxline:1, temp);
  674.     lineout('Enter comment: up to ' + temp + ' lines, enter empty line to quit.');
  675.     lineout(space);
  676.     linenum := 0;
  677.     assign(comfile, 'COMMENTS.BBS');
  678.     {$I-} reset(comfile) {$I+};
  679.     if IOresult <> 0 then rewrite(comfile);
  680.     seek(comfile, filesize(comfile));
  681.     head := caller;
  682.     if clockin then head := head + '  ' + timeon;
  683.     repeat
  684.       linenum := linenum + 1;
  685.       str(linenum:2, temp);
  686.       stringout(temp + ': ');
  687.       temp := inputstring(echo);
  688.       if temp <> '' then begin
  689.         if linenum = 1 then write(comfile, head);
  690.         write(comfile, temp);
  691.       end;
  692.     until (temp = '') or (linenum = maxline) or not cts;
  693.     close(comfile);
  694.   end;
  695.  
  696. function nextuser: integer;
  697.  
  698.   var temp: integer;
  699.  
  700.   begin
  701.     stringout('Finding space for new user: ');
  702.     temp := findid('***');
  703.     if temp = 0 then nextuser := 1 + filesize(idfile) else nextuser := temp;
  704.   end;
  705.  
  706. procedure savedefaults;
  707.  
  708.   begin
  709.     if usernum = 0 then usernum := nextuser;
  710.     with idrec do begin
  711.       user := caller;
  712.       if expert then exfl := 0 else exfl := 255;
  713.       if clockin then lsto := timeon;
  714.       lstm := nextmess-1;
  715.       pass := password;
  716.       clr := cs;
  717.       acc := access;
  718.       bsp := bs;
  719.       lnf := lf;
  720.       upc := caps;
  721.       wid := width;
  722.     end;
  723.     seek(idfile, usernum - 1);
  724.     write(idfile, idrec);
  725.   end;
  726.  
  727. procedure disconnect;
  728.  
  729.   var
  730.     ch: char;
  731.  
  732.   begin
  733.     clearsc;
  734.     if not expert then lineout('Answering question with other than "Y" or "N" returns to BBS:');
  735.     ch := getcap('Do you want to leave comments to the Sysop (Y/N)? ');
  736.     if ch = 'Y' then getcomments(15);
  737.     if (ch = 'N') or (ch = 'Y') or not cts then begin
  738.       connecttime;
  739.       lineout('Thanks for calling, ' + caller);
  740.       savedefaults;
  741.       hangup;
  742.     end;
  743.   end;
  744.